package ruleservice

import (
	"encoding/json"
	"vpn-management-server/logger"
	"vpn-management-server/src/dao"
	"vpn-management-server/src/dao/rgroupdao"
	"vpn-management-server/src/dao/ruledao"
	"vpn-management-server/src/dao/userdao"
	"vpn-management-server/src/model/rulemodel"
)

func DeleteRulesService(IDs []int) error {
	// TODO 规则和规则组
	err := ruledao.DeleteRulesFromAllRGroup(IDs)
	if err != nil {
		logger.Logger.Error("delete rule from rgroup_rules fail")
		return err
	}
	// TODO 规则和用户组
	err = ruledao.DeleteRulesFromAllUGroup(IDs)
	if err != nil {
		logger.Logger.Error("delete rule from ugroup_rules fail")
		return err
	}
	// TODO 规则和用户
	err = ruledao.DeleteRulesFromAllUser(IDs)
	if err != nil {
		logger.Logger.Error("delete rule from user_rules fail")
		return err
	}
	//TODO 规则
	err = ruledao.DeleteRules(IDs)
	if err != nil {
		logger.Logger.Error("delete rule from rule fail")
		return err
	}
	return nil
}

// DeleteRulesFromUGroupService 用户组管理员从用户组中删除规则
func DeleteRulesFromUGroupService(IDs []int, ugid int) error {
	// TODO 获取该用户组所有用户信息
	users := userdao.GetAllUserByUGroupID(ugid)
	//if users == nil {
	//	common.Logger.Warn("get user from users fail")
	//	return errors.New("get user from users fail")
	//}
	var userIDs []int
	for _, user := range users {
		userIDs = append(userIDs, user.ID)
	}
	logger.Logger.Debug("delete rule id:", IDs)
	logger.Logger.Debug("delete user id:", userIDs)
	// TODO 删除该用户组中用户和规则的关联
	err := ruledao.DeleteRulesFromUGroupUser(IDs, userIDs)
	if err != nil {
		logger.Logger.Error("delete rule from user_rules fail")
		return err
	}
	// TODO 获取到属于该用户组的规则组
	RGIDs := rgroupdao.GetRGroupIDsByUGroupID(ugid)
	// TODO 删除该用户组规则组和规则的关联
	for _, rgid := range RGIDs {

		err = ruledao.DeleteRulesFromRGroup(IDs, rgid)
		if err != nil {
			logger.Logger.Error("delete rule from rgroup_rules fail")
			return err
		}
	}
	// TODO 用户组中分配的规则设置IsDeleted = 1
	err = ruledao.RevokeRulesFromUGroup(IDs, ugid)
	if err != nil {
		logger.Logger.Error("revoke ugroup rule fail")
		return err
	}
	return nil
}

func DepriveRulesFromUGroupService(IDs []int, ugid int) error {
	err := DeleteRulesFromUGroupService(IDs, ugid)
	if err != nil {
		logger.Logger.Error("delete rule from ugroup fail")
		return err
	}
	//删除用户组和规则的关联
	err = ruledao.DeleteRulesFromUGroup(IDs, ugid)
	if err != nil {
		logger.Logger.Error("delete rule from ugroup_rules fail")
		return err
	}
	return nil
}

func DepriveAllRuleFromUserService(uid int) error {
	return ruledao.DepriveAllRuleFromUser(uid)
}

func DeleteRulesFromAllUGroupService(IDs []int, ugid int) error {
	// TODO 获取用户组所有用户信息
	users := userdao.GetAllUser()
	//if users == nil {
	//	common.Logger.Error("get user from users fail")
	//	return errors.New("get user from users fail")
	//}
	var userIDs []int
	for _, user := range users {
		userIDs = append(userIDs, user.ID)
	}
	// TODO 删除所有用户和规则的关联
	err := ruledao.DeleteRulesFromUGroupUser(IDs, userIDs)
	if err != nil {
		logger.Logger.Error("delete rule from user_rules fail")
		return err
	}
	// TODO 用户组规则中删除规则项
	err = ruledao.DeleteRulesFromUGroup(IDs, ugid)
	if err != nil {
		logger.Logger.Error("delete rule from ugroup_rules fail")
		return err
	}
	// TODO 获取到属于该用户组的规则组
	RGIDs := rgroupdao.GetRGroupIDsByUGroupID(ugid)
	// TODO 删除对应规则组中的规则
	for _, rgid := range RGIDs {
		err = ruledao.DeleteRulesFromRGroup(IDs, rgid)
		if err != nil {
			logger.Logger.Error("delete rule from rgroup_rules fail")
			return err
		}
	}
	return nil
}

// GetUserAllRulesService  获取用户所有规则 把规则组中的规则也取出来 和 规则合并在一起
func GetUserAllRulesService(uid int) []*rulemodel.Rule {
	rules := ruledao.GetUserRules(uid)
	// 在分配规则组的时候会分配对应的规则 因此不需要再获取用户规则组中的规则
	RGIDs := rgroupdao.GetRGroupIDsByUserID(uid)
	for _, rgid := range RGIDs {
		rules = append(rules, ruledao.GetRulesByRGroupID(rgid)...)
	}
	return rules
}

func GetAllRGroupRulesService(rid int) []*rulemodel.Rule {
	rules := ruledao.GetRulesByRGroupID(rid)
	return rules
}

func CompareRulesListService(old []*rulemodel.Rule, new []int) []int {
	var IDs []int
	for _, i := range old {
		for _, j := range new {
			if i.ID == j {
				IDs = append(IDs, j)
			}
		}
	}
	return IDs
}

func GetRuleIDsByRGroupIDService(rgid int) []int {
	var IDs []int
	rules := ruledao.GetRulesByRGroupID(rgid)
	for _, rule := range rules {
		IDs = append(IDs, rule.ID)
	}
	return IDs
}

func GetRulesByRGroupIDService(rgid int) []*rulemodel.Rule {
	return ruledao.GetRulesByRGroupID(rgid)
}

func GetRuleInfosByRGroupIDService(rgid int) []*rulemodel.RuleInfo {
	var ruleInfos []*rulemodel.RuleInfo
	RIDS := ruledao.GetRuleIDsByRGroupID(rgid)
	// 如果空 说明这个用户组中不存在规则 那么返回空即可
	if RIDS == nil {
		return ruleInfos
	}
	sqlStr := "SELECT id,name from rule where id = ?"
	for _, id := range RIDS {
		var ruleInfo rulemodel.RuleInfo
		if err := dao.GMysqlDB.Conn.Get(&ruleInfo, sqlStr, id); err != nil {
			logger.Logger.Error(err)
			return nil
		}
		ruleInfos = append(ruleInfos, &ruleInfo)
	}
	return ruleInfos
}

func GetUserRulesByNameService(name string) []*rulemodel.Rule {
	uid := userdao.GetUserIDByName(name)
	if uid == -1 {
		logger.Logger.Error("find id by user name fail")
		return nil
	}
	return GetUserAllRulesService(uid)
}

func GetUserRuleByMIN2(name string) []byte {
	if name == "" {
		return nil
	}

	rules := GetUserRulesByNameService(name)
	if rules == nil {
		logger.Logger.Warn("user rule is empty")
		rules = []*rulemodel.Rule{}
	}

	var resData = struct {
		Rules []*rulemodel.Rule
		Count int
	}{}
	resData.Rules = rules

	data, _ := json.Marshal(resData)
	logger.Logger.Info("get user rules by name success")

	return data
}
